// 12.20.12
// XBee RX/TX Library

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "XBeeDefine.h"
#include "XBee.h"

#define GCC_COMP 1

// Static declaration makes it private
// Maximum data size is 32 characters
static char txBuffer[32];

// There is where the information pulled from the
// buffer goes
static char rxBuffer[32];

int rxReturnInt(void)
{ 
	int returnMe = atoi(rxBuffer);
	clearAndFlush();
	return returnMe;	
}

char rxReturnChar(void)
{
	char returnMe = rxBuffer[0];
	clearAndFlush();
	return returnMe;
}

float rxReturnFloat(void)
{
	float returnMe = atof(rxBuffer);
	clearAndFlush();
	return returnMe;
}

double rxReturnDouble(void)
{
	printf("\tBUFFER: %s", rxBuffer);
	double returnMe = atol(rxBuffer);
	printf("\tRETURN ME: %f\n", returnMe);
	clearAndFlush();
	return returnMe;
}

void rxReturnString(char *str)
{
	int i;
	for(i=0; i<32; i++)
	{ str[i] = rxBuffer[i]; }
}

void clearAndFlush(void)
{
	int i;
	for(int i=0; i<32; i++)
	{ rxBuffer[i] = ' '; }
	
	#if !GCC_COMP
		// Delay for 10 ms to insure all data has come
		// into buffer before flushing
		delay(10);
		Serial.flush();
	#endif
}

// Returns 0 if timeout
int pullBuffer(void)
{
	#if !GCC_COMP
		// Timeout is used to check if there's no information
		// in the buffer. If there isn't anything, delay for
		// 5ms. It will only do this 5 times.
		int timeOut = 0, i = 0;
		
		while(1)
		{
			// Failed conditionals hit
			if(timeOut == 5 || i > 32)
			{
				clearAndFlush();
				return 0;
			}
			
			// No information in buffer and timeout hasn't been
			// hit. Delay and return to beginning of loop.
			if(Serial.available() == 0 && timeOut < 5)
			{
				delay(5);
				timeOut++;
				continue;
			}
			
			// Valid info passed, read from buffer
			rxBuffer[i] = Serial.read();
			i++;
			
			if(rxBuffer[i] == '\n')
			{ return 1; }
			
		}
	#endif
}

void transmit(void)
{
	int i;
	#if !GCC_COMP
		Serial.print(txBuffer);
	#else
		printf("Transmitted: %s", txBuffer);
		for(i=0; i<32; i++)
		{ rxBuffer[i] = txBuffer[i]; }
	#endif
	// Clear buffer after transmit
	for(i=0; i<32; i++)
	{ txBuffer[i] = ' '; }
}

// The loc is a pointer to the data and type is the
// prevously defined data type
void bufferData(void *loc, const int type)
{
	if(type == INT_TYPE)
	{
		// Create an integer pointer and cast the void
		// pointer as an integer pointer
		int *data = (int *)loc;
		// Convert the integer value in 'data' to a string
		sprintf(txBuffer, "%d", *data);
		// Concatinate newline to indicate end of packet
		strcat(txBuffer, "\n");
		
		return;
	}
	else if(type == CHAR_TYPE)
	{
		char *data = (char *)loc;
		// Since there is only one char, place in 0th position
		txBuffer[0] = *data;
		strcat(txBuffer, "\n");
		
		return;
	}
	else if(type == FLOAT_TYPE)
	{
		float *data = (float *)loc;
		sprintf(txBuffer, "%f", *data);
		strcat(txBuffer, "\n");
		
		return;
	}
	else if(type == DOUBLE_TYPE)
	{
		double *data = (double *)loc;
		sprintf(txBuffer, "%lf", *data);
		strcat(txBuffer, "\n");
		
		return;
	}
	else if(type == STRING_TYPE)
	{
		// Cast the string as a character pointer
		char *data = (char *)loc;
		// Copy data in buffer
		strcpy(&txBuffer[0], data);
		strcat(txBuffer, "\n");
		
		return;
	}
}
